import bpy, math
from . import blender_funcs

# just a DAE exporter.
# it was supposed to only rotate the meshes around the X axis by -90 degrees
# but above that it now checks for armature and vertex group stuff
# only exports the armature object selected    

# write_bmd_bdl_collada function
# function to write custom collada file for
# SuperBMD conversion
def write_bmd_bdl_collada(context, filepath, triangulate):
    
  # this thing is always needed for stuff
  scene = bpy.context.scene
  
  # if nothing is selected end the exporter
  if (scene.objects.active == None or scene.objects.active.type != 'ARMATURE'):
    if (scene.objects.active == None):
      blender_funcs.disp_msg("No Armature selected. Select one and try again.")
    else:
      blender_funcs.disp_msg("No Armature selected. Currently selecting: \"%s\""
                             % (scene.objects.active.name))
    return {'FINISHED'}
  
  # get armature object
  armature = scene.objects.active  
  print("\nArmature found: \"%s\"" % (armature.name))
  
  # check if the armature contains only mesh objects inside
  for obj in armature.children:
    if (obj.type != 'MESH'):
      blender_funcs.disp_msg("\"%s\": contains non-mesh object (%s)."
                             % (armature.name, obj.name))
      return {'FINISHED'}
  
  # check if all meshes have an armature modifier that is
  # assigned to the armature object and it is binded to
  # vertex groups if none of those are just create them,
  # I don't think it is bad to automate that
  for mesh in armature.children:
    if("Armature" not in mesh.modifiers):
      blender_funcs.disp_msg("\"%s\": has no armature modifier. Adding one..." % (mesh.name))
      blender_funcs.select_obj(scene, mesh, False)
      bpy.ops.object.modifier_add(type = 'ARMATURE')
      mesh.modifiers["Armature"].object = armature
      mesh.modifiers["Armature"].use_vertex_groups = True
    else: # ensure bind is to a vertex group
      if (mesh.modifiers["Armature"].use_vertex_groups == False):
        blender_funcs.disp_msg("\"%s\": armature modifier wasn't binded to vertex groups"
                               % (mesh.name))
        mesh.modifiers["Armature"].use_vertex_groups = True
  
  # check if all the vertex groups in each mesh correspond to the name of a skeleton bone
  bone_name_list = []
  for bone in armature.data.bones:
    bone_name_list.append(bone.name)  
  # vertex group check
  for mesh in armature.children:
    for v_group in mesh.vertex_groups:
      if (v_group.name not in bone_name_list):
        blender_funcs.disp_msg(("\"%s\": contains non-valid vert group \"%s\"." 
                               % (mesh.name, v_group.name)) + " Unable to continue.")
        return {'FINISHED'}
  # vertex weight check
  for mesh in armature.children:
    for vertex in mesh.data.vertices:
      if (len(vertex.groups) == 0):
        blender_funcs.disp_msg(("\"%s\": contains unweighted vertices."
                               % (mesh.name)) + " Unable to continue.")
        return {'FINISHED'}
  
  # get the object names
  obj_name = armature.name
  child_names = []
  for child in armature.children:
    child_names.append(child.name)
  
  # change to object view and make a copy of the armature object (with its children)
  bpy.ops.object.mode_set(mode='OBJECT')  
  blender_funcs.select_obj(scene, armature, True)
  bpy.ops.object.duplicate(linked = True)
  bpy.ops.object.make_single_user(type = 'SELECTED_OBJECTS', object = True, obdata = True)
  old_armature = armature
  armature = scene.objects.active
  blender_funcs.select_obj(scene, armature, False)
  
  # apply the transformations to the armature
  armature.rotation_euler[0] = math.radians(-90)
  armature.scale = 100 * armature.scale
  bpy.ops.object.transform_apply(location = True, rotation = True, scale = True)
   
  # apply the transformations to the meshes inside the armature
  for i in range(0, len(armature.children)):
    blender_funcs.select_obj(scene, armature.children[i], False)
    bpy.ops.object.transform_apply(location = True, rotation = True, scale = True)
  blender_funcs.select_obj(scene, armature, False)
  
  # handle the object names so that they match the original model names
  armature.name = obj_name
  armature.data.name = obj_name
  for i in range(0, len(armature.children)):
    armature.children[i].name = child_names[i] 
    armature.children[i].data.name = child_names[i] 
  
  # export the object
  bpy.ops.wm.collada_export(filepath = filepath, use_blender_profile = False,
                            selected = True, include_children = True,
                            triangulate = triangulate)  
  
  # delete the duplicate object
  blender_funcs.select_obj(scene, armature, True)
  bpy.ops.object.delete(use_global = False)
  
  # re-assign the original object names
  armature = old_armature
  armature.name = obj_name
  armature.data.name = obj_name
  for i in range(0, len(armature.children)):
    armature.children[i].name = child_names[i] 
    armature.children[i].data.name = child_names[i] 
  
  # done!
  blender_funcs.select_obj(scene, armature, False)
  blender_funcs.disp_msg("Armature \"%s\" exported!" % (armature.name))
  return {'FINISHED'}

# Stuff down is for the menu appending
# of the exporter to work plus some setting stuff
# comes from a Blender importer template
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator

class export_superbmd_collada(Operator, ExportHelper):
  """Export a Collada file for SuperBMD (SuperBMD only)"""
  bl_idname = "export_scene.superbmd_collada"
  bl_label = "Export SuperBMD Collada (.DAE)"
  filename_ext = ".dae"
  filter_glob = StringProperty(default = "*.dae", options = {'HIDDEN'}, maxlen = 255)
    
  triangulate = BoolProperty(name = "Triangulate meshes",
                             description = "Triangulate meshes inside armatures",
                             default = False)
  def execute(self, context):
    return write_bmd_bdl_collada(context, self.filepath, self.triangulate)

# Only needed if you want to add into a dynamic menu
def menu_export_superbmd_collada(self, context):
  self.layout.operator(export_superbmd_collada.bl_idname, text="SuperBMD Collada (.dae)")

bpy.utils.register_class(export_superbmd_collada)
bpy.types.INFO_MT_file_export.append(menu_export_superbmd_collada)

# test call
bpy.ops.export_scene.superbmd_collada('INVOKE_DEFAULT')
